/**
  * 图片button类
  * by dily
  * (c) copyright 2014 - 2035
  * All Rights Reserved. 
  * 可以有图片，文字，动画
  * todo:九宫格、多动画、图字等
  */

class GamePanel extends BasePanel {

    // 资源
    private mahjong_assets: egret.SpriteSheet = RES.getRes("mahjong");
    private table_assets: egret.SpriteSheet = RES.getRes("table");
    // 桌背景
    private bg;
    // 房间id
    private room_id = ""
    // 用户id
    private uid = ""
    private center_pos;
    private center_out;
    // 当前玩家
    private current_pos;
    // 玩家座位
    private seat = {
        south: -1,
        north: -1,
        east: -1,
        west: -1
    }
    // 手牌
    private south_tiles = [];
    private west_tile = 0
    private east_tile = 0
    private north_tile = 0
    // 打出的牌
    private south_out = []
    private west_out = []
    private east_out = []
    private north_out = []

    private tile_padding = 80

    // 吃碰杠的牌
    private west_opt = []
    private east_opt = []
    private north_opt = []
    private south_opt = []
    // 庄家
    private banker: number;
    // 骰子点数
    private dice: number;
    // 当前牌桌玩家
    private users = [{ uid: '' }];
    // 打出的牌的位置
    private pos = {
        north: { x: 0, y: 0 },
        west: { x: 0, y: 0 },
        east: { x: 0, y: 0 },
        south: { x: 0, y: 0 }
    }
    public constructor() {
        super();
        this.init_socket();
        this.init()
    }

    private init_socket(): void {
        SocketManager.connectServer('http://172.16.112.136:10086')
        Global.addEventListener('connect', this.connect, this)
        Global.addEventListener('game_msg', this.msg_handler, this)
    }
    private msg_handler({param}) {
        let {
            action,
            body
        } = param
        switch (action) {
            case Config.ACTION_RESULT.join_room_result:
                let {
                    room_id,
                    source_id,
                    is_me
                } = body
                this.room_id = room_id
                localStorage.setItem('room_id', room_id)
                this.users = body.players
                // 只有在自己加入房间后,才回去主动触发准备
                if (is_me) {
                    SocketManager.sendMessage({
                        cmd: Config.CMD.ROOM,
                        action: Config.ACTION.ready,
                        body: {
                            room_id: body.room_id,
                            is_ready: true
                        }
                    })
                }
                this.get_seat()
                break
            case Config.ACTION_RESULT.ready_result:
                this.users = body.players
                break
            case Config.ACTION_RESULT.unready_result:
                this.users = body.players
                break
            case Config.ACTION_RESULT.leave_room_result:
                this.users = body.players
                break
            case Config.ACTION_RESULT.game_start_result:

                break;
            case Config.ACTION_RESULT.banker_result:
                this.banker = body
                break
            case Config.ACTION_RESULT.die_result:
                this.dice = body
                break
            case Config.ACTION_RESULT.deal_result:
                this.south_tiles = body[this.seat.south].sort((item1, item2) => item1 - item2)
                this.north_tile = body[this.seat.north]
                this.west_tile = body[this.seat.west]
                this.east_tile = body[this.seat.east]
        }
        this.paint()
    }
    private get_seat() {
        let south = 0
        let count = this.users.length
        for (let i = 0; i < count; i++) {
            let u = this.users[i]
            if (u && u.uid === this.uid) {
                south = i
                break
            }
        }

        let west = south - 1 < 0 ? count - 1 : south - 1
        let east = south + 1 >= count ? 0 : south + 1
        let v = south + 2
        let north = v >= count ? v - count : v

        this.seat = {
            north,
            south,
            east,
            west
        }
    }
    private connect({param}) {
        this.uid = param
        let room_id = localStorage.getItem('room_id')
        SocketManager.sendMessage(room_id ? {
            cmd: Config.CMD.ROOM,
            action: Config.ACTION.join_room,
            body: { room_id }
        } : {
                cmd: Config.CMD.ROOM,
                action: Config.ACTION.join_room
            })
    }
    private init(): void {
        let {
            center_pos_width,
            out_tile_south_height,
            out_tile_east_right,
            out_tile_west_height,
            out_tile_west_width,
            out_tile_south_left,
            out_tile_west_left
        } = GameConfig
        let padding = 80
        this.pos.north = {
            y: this.h / 2 - center_pos_width / 2 - out_tile_south_height - this.tile_padding,
            x: this.w - out_tile_east_right - out_tile_west_height
        }
        this.pos.south = {
            x: out_tile_south_left,
            y: this.h / 2 + center_pos_width / 2 + this.tile_padding
        }
        this.pos.west = {
            x: out_tile_west_left,
            y: this.h / 2 - center_pos_width / 2 - this.tile_padding - out_tile_south_height
        }
        this.pos.east = {
            x: this.w - out_tile_east_right,
            y: this.h / 2 + center_pos_width / 2 + this.tile_padding + out_tile_west_height - out_tile_west_width
        }

        // 绘制背景
        this.bg = new egret.Bitmap();
        this.bg.width = GameConfig.curWidth();
        this.bg.height = GameConfig.curHeight();
        this.bg.texture = RES.getRes('game_bg');
        this.addChild(this.bg);
    }
    private paint() {
        // 绘制玩家方向
        this.draw_pos()

        // 牌面
        this.draw_tile()

        // 绘制出手的牌
        this.draw_out_tile()

        // 绘制 吃碰杠
        this.draw_opt()

        // 绘制用户信息
        this.draw_user()
    }
    private draw_user() {
        this.draw_north_user()
        this.draw_south_user()
        this.draw_west_user()
        this.draw_east_user()
    }
    private draw_north_user() {
        let user = this.users[this.seat.north]
        if (!user) { return }
        let {
            tile_margin_left,
            other_tile_width,
            out_tile_west_width,
            tile_margin_top
        } = GameConfig
        let uid = user.uid
        let avatar_texture = new egret.Bitmap(this.table_assets.getTexture('avatar-3'))
        let name_text = new egret.TextField()

        avatar_texture.width = 100
        avatar_texture.height = 100
        name_text.x = avatar_texture.x = this.w - tile_margin_left - other_tile_width - this.tile_padding - out_tile_west_width - 100
        avatar_texture.y = tile_margin_top
        name_text.y = tile_margin_top + 120
        name_text.text = uid

        this.addChild(name_text)
        this.addChild(avatar_texture)
    }
    private draw_south_user() {
        let user = this.users[this.seat.south]
        if (!user) { return }
        let {
            tile_margin_left,
            other_tile_width,
            tile_margin_bottom,
            tile_margin_top
        } = GameConfig
        let uid = user.uid
        let avatar_texture = new egret.Bitmap(this.table_assets.getTexture('avatar-2'))
        let name_text = new egret.TextField()

        avatar_texture.width = 100
        avatar_texture.height = 100
        name_text.x = avatar_texture.x = tile_margin_left + other_tile_width + this.tile_padding / 2
        avatar_texture.y = this.h - tile_margin_bottom - 140
        name_text.y = this.h - tile_margin_bottom - 30
        name_text.text = uid

        this.addChild(name_text)
        this.addChild(avatar_texture)
    }
    private draw_west_user() {
        let user = this.users[this.seat.west]
        if (!user) {
            return
        }
        let {
            tile_margin_left,
            other_tile_width,
            tile_margin_bottom,
            tile_margin_top
        } = GameConfig
        let uid = user.uid
        let avatar_texture = new egret.Bitmap(this.table_assets.getTexture('avatar-1'))
        let name_text = new egret.TextField()

        avatar_texture.width = 100
        avatar_texture.height = 100
        name_text.x = avatar_texture.x = tile_margin_left / 2 - 50
        avatar_texture.y = this.h / 2 - 50
        name_text.y = this.h / 2 + 60
        name_text.text = uid

        this.addChild(name_text)
        this.addChild(avatar_texture)
    }
    private draw_east_user() {
        let user = this.users[this.seat.east]
        if (!user) {
            return
        }
        let {
            tile_margin_left,
            other_tile_width,
            tile_margin_bottom,
            tile_margin_top
        } = GameConfig
        let uid = user.uid
        let avatar_texture = new egret.Bitmap(this.table_assets.getTexture('avatar-4'))
        let name_text = new egret.TextField()

        avatar_texture.width = 100
        avatar_texture.height = 100
        name_text.x = avatar_texture.x = this.w - tile_margin_left / 2 - 50
        avatar_texture.y = this.h / 2 - 50
        name_text.y = this.h / 2 + 60
        name_text.text = uid

        this.addChild(name_text)
        this.addChild(avatar_texture)
    }
    /**
     * 绘制中间部分
     */
    private draw_pos() {
        let w = GameConfig.center_pos_width
        // 绘制中间部分, 倒计时, 玩家方向
        this.center_pos = new egret.Bitmap();
        this.center_pos.texture = this.table_assets.getTexture("TimerImage0");
        this.center_pos.width = w
        this.center_pos.height = w
        this.center_pos.x = this.w / 2 - w / 2;
        this.center_pos.y = this.h / 2 - w / 2;
        this.addChild(this.center_pos)

        // 绘制玩家方向
        this.center_out = new egret.Bitmap();
        this.center_out.texture = this.table_assets.getTexture("TimerImage");
        this.center_out.width = w
        this.center_out.height = w
        this.center_out.x = this.w / 2 - w / 2;
        this.center_out.y = this.h / 2 - w / 2;
        this.addChild(this.center_out)

        // 绘制当前玩家
        this.active_player('south')
    }
    // 绘制当前玩家指向
    private active_player(direct) {
        this.current_pos && this.removeChild(this.current_pos)
        this.current_pos = new egret.Bitmap();
        let w = GameConfig.center_pos_width
        switch (direct) {
            case 'north':
                this.current_pos.texture = this.table_assets.getTexture("TimerImage1");
                this.current_pos.width = w
                this.current_pos.height = w / 2 - 35
                this.current_pos.x = this.w / 2 - w / 2;
                this.current_pos.y = this.h / 2 - w / 2;
                break;
            case 'south':
                this.current_pos.texture = this.table_assets.getTexture("TimerImage2");
                this.current_pos.width = w
                this.current_pos.height = w / 2 - 35
                this.current_pos.x = this.w / 2 - w / 2;
                this.current_pos.y = this.h / 2 + 40;
                break;
            case 'east':
                this.current_pos.texture = this.table_assets.getTexture("TimerImage13");
                this.current_pos.width = w / 2 - 35
                this.current_pos.height = w
                this.current_pos.x = this.w / 2 + 40;
                this.current_pos.y = this.h / 2 - w / 2;
                break;
            case 'west':
                this.current_pos.texture = this.table_assets.getTexture("TimerImage4");
                this.current_pos.width = w / 2 - 35
                this.current_pos.height = w
                this.current_pos.x = this.w / 2 - w / 2;
                this.current_pos.y = this.h / 2 - w / 2;
                break;
        }
        this.addChild(this.current_pos)
    }
    // 绘制所有玩家的牌
    private draw_tile() {
        this.draw_south_tile()
        this.draw_west_tile()
        this.draw_east_tile()
        this.draw_north_tile()
    }
    // 绘制出手的牌
    private draw_out_tile() {
        this.draw_south_out_tile()
        this.draw_north_out_tile()
        this.draw_west_out_tile()
        this.draw_east_out_tile()

    }
    // 绘制  吃碰杠 
    private draw_opt() {
        this.draw_south_opt()
        this.draw_north_opt()
        this.draw_west_opt()
        this.draw_east_opt()
    }
    private draw_south_opt() {
        let len = this.south_opt.length
        let {
            out_tile_south_width,
            out_tile_south_height,
            out_tile_west_width,
            tile_height,
            tile_margin_bottom
        } = GameConfig
        for (let i = 0; i < len; i++) {
            let opt = this.south_opt[i]
            for (let index = 0, i_len = opt.length; index < i_len; index++) {
                let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`${this.south_out[i]}`))
                let tile_bg = new egret.Bitmap(this.mahjong_assets.getTexture('tile_bule_8'))

                tile_bg.width = tile.width = out_tile_south_width
                tile_bg.height = tile.height = out_tile_south_height
                tile_bg.x = tile.x = this.pos.west.x + (index + i * i_len) * out_tile_south_width + i * this.tile_padding
                tile_bg.y = tile.y = this.h - tile_height - tile_margin_bottom - this.tile_padding

                this.addChild(tile_bg)
                this.addChild(tile)
            }
        }
    }
    private draw_north_opt() {
        let len = this.north_opt.length
        let {
            out_tile_south_width,
            out_tile_south_height,
            out_tile_west_width,
            tile_margin_top,
        } = GameConfig
        for (let i = 0; i < len; i++) {
            let opt = this.north_opt[i]
            for (let index = 0, i_len = opt.length; index < i_len; index++) {
                let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`${this.south_out[i]}`))
                let tile_bg = new egret.Bitmap(this.mahjong_assets.getTexture('tile_bule_8'))

                tile_bg.width = tile.width = out_tile_south_width
                tile_bg.height = tile.height = out_tile_south_height
                tile_bg.x = tile.x = this.pos.east.x - (index + i * i_len) * out_tile_south_width - i * this.tile_padding - out_tile_west_width
                tile_bg.y = tile.y = tile_margin_top + out_tile_south_height + this.tile_padding

                this.addChild(tile_bg)
                this.addChild(tile)
            }
        }
    }
    private draw_west_opt() {
        let len = this.west_opt.length
        let {
            out_tile_west_width,
            out_tile_west_height,
            out_tile_south_height,
            tile_margin_left,
            other_tile_width
        } = GameConfig
        for (let i = 0; i < len; i++) {
            let opt = this.west_opt[i]
            for (let index = 0, i_len = opt.length; index < i_len; index++) {
                let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`l-${this.west_out[i]}`))
                let tile_bg = new egret.Bitmap(this.mahjong_assets.getTexture('tile_bule_5'))

                tile_bg.width = tile.width = out_tile_west_width
                tile_bg.height = tile.height = out_tile_west_height
                tile_bg.x = tile.x = tile_margin_left + other_tile_width + this.tile_padding / 2
                tile_bg.y = tile.y = this.pos.north.y - out_tile_south_height * 2 + (index + i * i_len) * out_tile_west_height + i * this.tile_padding

                this.addChild(tile_bg)
                this.addChild(tile)
            }
        }
    }
    private draw_east_opt() {
        let len = this.east_opt.length
        let {
            out_tile_west_width,
            out_tile_west_height,
            out_tile_south_height,
            tile_margin_left,
            other_tile_width
        } = GameConfig
        for (let i = 0; i < len; i++) {
            let opt = this.east_opt[i]
            for (let index = 0, i_len = opt.length; index < i_len; index++) {
                let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`r-${this.west_out[i]}`))
                let tile_bg = new egret.Bitmap(this.mahjong_assets.getTexture('tile_bule_5'))

                tile_bg.width = tile.width = out_tile_west_width
                tile_bg.height = tile.height = out_tile_west_height
                tile_bg.x = tile.x = this.w - tile_margin_left - other_tile_width - this.tile_padding - out_tile_west_width
                tile_bg.y = tile.y = this.pos.north.y - out_tile_south_height * 2 + (index + i * i_len) * out_tile_west_height + i * this.tile_padding

                this.addChild(tile_bg)
                this.addChild(tile)
            }
        }
    }
    private draw_south_out_tile() {
        let {
            out_tile_south_width,
            out_tile_south_height,
            out_tile_west_width
        } = GameConfig
        let max_width = this.pos.east.x - this.pos.west.x - out_tile_west_width - this.tile_padding * 3
        let col_count = Math.floor(max_width / out_tile_south_width)
        for (let i = 0, len = this.south_out.length; i < len; i++) {
            let col = out_tile_south_width * i / max_width
            let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`${this.south_out[i]}`))
            let tile_bg = new egret.Bitmap(this.mahjong_assets.getTexture('tile_bule_8'))

            tile_bg.width = tile.width = out_tile_south_width
            tile_bg.height = tile.height = out_tile_south_height

            if (col > 1) {
                tile_bg.x = tile.x = this.pos.south.x + this.tile_padding + out_tile_south_width * (i - Math.floor(col) - col_count * Math.floor(col))
                tile_bg.y = tile.y = this.pos.south.y + Math.floor(col) * out_tile_south_height
            } else {
                tile_bg.x = tile.x = this.pos.south.x + this.tile_padding + out_tile_south_width * i
                tile_bg.y = tile.y = this.pos.south.y
            }
            this.addChild(tile_bg)
            this.addChild(tile)
        }
    }
    private draw_west_out_tile() {
        let {
            out_tile_west_width,
            out_tile_west_height,
        } = GameConfig
        let max_height = this.pos.south.y - this.pos.north.y
        let col_count = Math.floor(max_height / out_tile_west_height)

        for (let i = 0, len = this.west_out.length; i < len; i++) {
            let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`l-${this.west_out[i]}`))
            let tile_bg = new egret.Bitmap(this.mahjong_assets.getTexture('tile_bule_5'))

            let col = out_tile_west_height * i / max_height
            // 一列最多有几个麻将
            tile_bg.width = tile.width = out_tile_west_width
            tile_bg.height = tile.height = out_tile_west_height
            if (col > 1) {
                tile_bg.x = tile.x = this.pos.west.x - Math.floor(col) * out_tile_west_width
                tile_bg.y = tile.y = this.pos.west.y + out_tile_west_height * (i - Math.floor(col) - col_count * Math.floor(col))
            } else {
                tile_bg.x = tile.x = this.pos.west.x
                tile_bg.y = tile.y = this.pos.west.y + out_tile_west_height * i
            }

            this.addChild(tile_bg)
            this.addChild(tile)
        }
    }
    private draw_north_out_tile() {
        let {
            out_tile_south_width,
            out_tile_south_height,
            out_tile_west_width
        } = GameConfig
        let max_width = this.pos.east.x - this.pos.west.x - out_tile_west_width - this.tile_padding * 3
        let col_count = Math.floor(max_width / out_tile_south_width)
        for (let i = 0, len = this.south_out.length; i < len; i++) {
            let col = out_tile_south_width * i / max_width
            let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`${this.south_out[i]}`))
            let tile_bg = new egret.Bitmap(this.mahjong_assets.getTexture('tile_bule_7'))

            tile_bg.width = tile.width = out_tile_south_width
            tile_bg.height = tile.height = out_tile_south_height

            if (col > 1) {
                tile_bg.x = tile.x = this.pos.north.x - this.tile_padding - out_tile_south_width * (i - Math.floor(col) - col_count * Math.floor(col))
                tile_bg.y = tile.y = this.pos.north.y - Math.floor(col) * out_tile_south_height
            } else {
                tile_bg.x = tile.x = this.pos.north.x - out_tile_south_width * i - this.tile_padding
                tile_bg.y = tile.y = this.pos.north.y
            }

            this.addChild(tile_bg)
            this.addChild(tile)
        }
    }
    private draw_east_out_tile() {
        let {
            out_tile_west_width,
            center_pos_width,
            out_tile_west_height,
            out_tile_east_right,
            out_tile_south_height
        } = GameConfig
        let max_height = this.pos.south.y - this.pos.north.y
        let col_count = Math.floor(max_height / out_tile_west_height)

        for (let i = 0, len = this.east_out.length; i < len; i++) {
            let col = out_tile_west_height * i / max_height
            let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`r-${this.east_out[i]}`))
            let tile_bg = new egret.Bitmap(this.mahjong_assets.getTexture('tile_bule_5'))

            tile_bg.width = tile.width = out_tile_west_width
            tile_bg.height = tile.height = out_tile_west_height

            if (col > 1) {
                tile_bg.x = tile.x = this.pos.east.x + Math.floor(col) * out_tile_west_width
                tile_bg.y = tile.y = this.pos.east.y - out_tile_west_height * (i - Math.floor(col) - col_count * Math.floor(col))
            } else {
                tile_bg.x = tile.x = this.pos.east.x
                tile_bg.y = tile.y = this.pos.east.y - out_tile_west_height * i
            }


            this.addChild(tile_bg)
            this.addChild(tile)
        }
    }
    /**
     * 绘制自己的手牌
     */
    private draw_south_tile() {
        for (let i = 0, len = this.south_tiles.length; i < len; i++) {
            let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`${this.south_tiles[i]}`))
            let tile_bg = new egret.Bitmap(this.mahjong_assets.getTexture('tile_bule_7'))

            tile_bg.width = tile.width = GameConfig.tile_width
            tile_bg.height = tile.height = GameConfig.tile_height
            tile_bg.x = tile.x = (this.w - GameConfig.tile_width * this.south_tiles.length) / 2 + GameConfig.tile_width * i
            tile_bg.y = tile.y = this.h - GameConfig.tile_height - GameConfig.tile_margin_bottom

            this.addChild(tile_bg)
            this.addChild(tile)
        }
    }
    /**
     * 绘制对家手牌
     */
    private draw_north_tile() {
        let w = GameConfig.north_tile_width
        let h = GameConfig.north_tile_height
        let len = this.north_tile
        for (let i = 0; i < len; i++) {
            let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`tile_bule_4`))

            tile.width = w
            tile.height = h
            tile.x = (this.w - w * len) / 2 + w * i
            tile.y = GameConfig.tile_margin_top

            this.addChild(tile)
        }
    }
    /** 
     * 绘制下家手牌
     */
    private draw_east_tile() {
        let w = GameConfig.other_tile_width
        let h = GameConfig.other_tile_height
        let len = this.east_tile

        for (let i = 0; i < len; i++) {
            let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`tile_bule_3`))

            tile.width = w
            tile.height = h
            tile.x = this.w - w - GameConfig.tile_margin_left
            tile.y = (this.h - h * len) / 2 + h * i

            this.addChild(tile)
        }
    }
    /**
     * 绘制上家手牌
     */
    private draw_west_tile() {
        let w = GameConfig.other_tile_width
        let h = GameConfig.other_tile_height
        let len = this.east_tile

        for (let i = 0; i < len; i++) {
            let tile = new egret.Bitmap(this.mahjong_assets.getTexture(`tile_bule_6`))

            tile.width = w
            tile.height = h
            tile.x = GameConfig.tile_margin_left
            tile.y = (this.h - h * len) / 2 + h * i

            this.addChild(tile)
        }
    }
    private ready(e): void {

    }
}